<template>
  <j-modal
    :confirmLoading="confirmLoading"
    :maskClosable="false"
    :title="title"
    :visible="visible"
    :width="1200"
    @cancel="handleCancel"
    switchFullscreen
  >
    <a-spin :spinning="confirmLoading">
      <!-- 主表单区域 -->
      <a-form :form="form">
        <a-row>
          <a-col :sm="12" :xs="24">
            <a-form-item :labelCol="labelCol" :wrapperCol="wrapperCol" label="库存调整名称">
              <a-input :disabled="formDisabled" placeholder="请输入库存调整名称" v-decorator="['adjustName']"></a-input>
            </a-form-item>
          </a-col>
          <a-col :sm="12" :xs="24">
            <a-form-item :labelCol="labelCol" :wrapperCol="wrapperCol" label="调整类型">
              <j-dict-select-tag
                :disabled="formDisabled"
                :trigger-change="true"
                dictCode="adjust_type"
                placeholder="请选择调整类型"
                type="list"
                v-decorator="['adjustType', validatorRules.adjustType]"
              />
            </a-form-item>
          </a-col>
          <a-col :sm="12" :xs="24">
            <a-form-item :labelCol="labelCol" :wrapperCol="wrapperCol" label="调整前仓库">
              <j-search-select-tag
                :disabled="formDisabled"
                :list-data.sync="storeList"
                dict="biz_store,store_name,id"
                v-decorator="['fromStoreId', validatorRules.storeId]"
              />
            </a-form-item>
          </a-col>
          <a-col :sm="12" :xs="24" v-show="isShowToStoreId">
            <a-form-item :labelCol="labelCol" :wrapperCol="wrapperCol" label="调整后仓库">
              <j-search-select-tag
                :disabled="formDisabled"
                :list-data.sync="storeList"
                dict="biz_store,store_name,id"
                v-decorator="['toStoreId', validatorRules.storeId]"
              />
            </a-form-item>
          </a-col>
        </a-row>
        <a-row>
          <a-col :sm="12" :xs="24">
            <a-form-item :labelCol="labelCol" :wrapperCol="wrapperCol" label="调整原因">
              <a-textarea :disabled="formDisabled" auto-size v-decorator="['adjustReason']" />
            </a-form-item>
          </a-col>
          <a-col :sm="12" :xs="24">
            <a-form-item :labelCol="labelCol" :wrapperCol="wrapperCol" label="审批备注">
              <a-textarea :disabled="title !== '审批'" auto-size v-decorator="['remark']" />
            </a-form-item>
          </a-col>
        </a-row>
      </a-form>

      <!-- 子表单区域 -->
      <a-tabs @change="handleChangeTabs" v-model="activeKey">
        <a-tab-pane :forceRender="true" :key="refKeys[0]" tab="库存调整明细表">
          <j-editable-table
            :actionButton="!formDisabled"
            :columns="stockAdjustApprovalDetailTable.columns"
            :dataSource="stockAdjustApprovalDetailTable.dataSource"
            :disabled="formDisabled"
            :loading="stockAdjustApprovalDetailTable.loading"
            :maxHeight="300"
            :ref="refKeys[0]"
            :rowKey="(record) => record.id"
            :rowNumber="true"
            :rowSelection="!formDisabled"
            @added="rowAdd"
            @deleted="rowDel"
          >
            <template #goodsIdSlot="slotProps">
              <a-select
                :disabled="formDisabled"
                :filter-option="filterOption"
                @change="goodsIdChange(slotProps, $event)"
                @focus="goodsIdFocus(slotProps)"
                allowClear
                option-filter-prop="children"
                show-search
                style="width: 100%"
                v-model="tableRows[slotProps.rowId].goodsId"
              >
                <a-select-option
                  :key="item.goodsId"
                  :value="item.goodsId"
                  v-for="item in tableRows[slotProps.rowId].goodsList"
                >
                  {{ item.goodsName }}
                </a-select-option>
              </a-select>
            </template>

            <template #goodsSkuSlot="slotProps">
              <a-select
                :disabled="formDisabled"
                @change="specsChange(slotProps, $event)"
                @focus="specsFocus(slotProps)"
                allowClear
                style="width: 100%"
                v-model="tableRows[slotProps.rowId].goodsSpec"
              >
                <a-select-option
                  :key="item.specsId"
                  :value="item.specsId"
                  v-for="item in tableRows[slotProps.rowId].specsList"
                >
                  {{ item.specsName + '；数量:' + item.num }}
                </a-select-option>
              </a-select>
            </template>

            <template #adjustStockSlot="slotProps">
              <a-input-number
                :disabled="formDisabled"
                :precision="4"
                style="width: 100%"
                v-model="tableRows[slotProps.rowId].adjustStock"
              />
            </template>
          </j-editable-table>
        </a-tab-pane>
      </a-tabs>
    </a-spin>
    <template slot="footer">
      <div v-if="formDisabled && title == '审批'">
        <a-button @click="handleApproval(2)" key="back"> 驳回</a-button>
        <a-button @click="handleApproval(1)" key="submit" type="primary"> 通过</a-button>
      </div>
      <div v-if="formDisabled && title == '详情'">
        <a-button @click="handleCancel" key="back"> 关闭</a-button>
      </div>
      <div v-if="!formDisabled">
        <a-button @click="handleCancel" key="back"> 关闭</a-button>
        <a-button @click="handleOk" key="submit" type="primary"> 确定</a-button>
      </div>
    </template>
  </j-modal>
</template>

<script>
import pick from 'lodash.pick'
import { FormTypes, getRefPromise } from '@/utils/JEditableTableUtil'
import { JEditableTableMixin } from '@/mixins/JEditableTableMixin'
import JDictSelectTag from '@/components/dict/JDictSelectTag'
import JSearchSelectTag from '@/components/dict/JSearchSelectTag'
import { getQueryByGoodsId, getQueryBySpaceId, getStockPosition, postStockApproval } from '@/api/storeApproval'

export default {
  name: 'StockAdjustApprovalModal',
  mixins: [JEditableTableMixin],
  components: {
    JDictSelectTag,
    JSearchSelectTag,
  },
  computed: {
    formDisabled() {
      return this.disableSubmit
    },
  },
  watch: {
    storeList: {
      handler(n, o) {
        if (n) this.setStoreDefault(n[0].value)
      },
    },
  },
  data() {
    return {
      /** 表单 */
      storeList: null,
      isShowToStoreId: 1, // 调整后仓库项 显隐性
      /** 表格 */
      tableRows: {},
      //======================================================
      max: 10000,
      min: 0,
      fromStoreId: '',
      toStoreId: '',

      stockPositionList: [],
      fromSpaceData: {},
      aTextareaVal: '',
      disableSubmit: false,
      labelCol: {
        xs: { span: 24 },
        sm: { span: 6 },
      },
      wrapperCol: {
        xs: { span: 24 },
        sm: { span: 16 },
      },
      labelCol2: {
        xs: { span: 24 },
        sm: { span: 3 },
      },
      wrapperCol2: {
        xs: { span: 24 },
        sm: { span: 20 },
      },
      // 新增时子表默认添加几行空数据
      addDefaultRowNum: 0,
      validatorRules: {
        storeId: {
          rules: [
            { required: true, message: '请选择仓库!' },
            {
              validator: this.stockIdValdator,
            },
          ],
        },
        adjustType: {
          rules: [
            { required: true, message: '请选择调整类型!' },
            {
              validator: this.adjustTypeValdator,
            },
          ],
        },
      },
      refKeys: ['stockAdjustApprovalDetail'],
      tableKeys: ['stockAdjustApprovalDetail'],
      activeKey: 'stockAdjustApprovalDetail',
      // 库存调整明细表
      stockAdjustApprovalDetailTable: {
        loading: false,
        dataSource: [],
        columns: [
          {
            // table 调整前仓位
            title: '',
            key: 'fromSpaceId',
            type: FormTypes.sel_search,
            options: [],
            width: '200px',
            placeholder: '请输入${title}',
            defaultValue: '',
            validateRules: [
              {
                required: true,
                message: '${title}不能为空',
                handler: this.fromSpaceIdChange,
              },
            ],
          },
          {
            title: '调整后仓位',
            key: 'toSpaceId',
            type: FormTypes.hidden,
            options: [],
            width: '200px',
            placeholder: '请输入${title}',
            defaultValue: '',
            validateRules: [
              {
                handler: this.toSpaceIdChange,
              },
            ],
          },
          {
            title: '商品',
            key: 'goodsId',
            type: FormTypes.slot,
            width: '200px',
            placeholder: '请输入${title}',
            defaultValue: '',
            slotName: 'goodsIdSlot',
          },
          {
            title: '规格',
            key: 'goodsSpec',
            type: FormTypes.slot,
            width: '300px',
            placeholder: '请输入${title}',
            defaultValue: '',
            slotName: 'goodsSkuSlot',
          },
          {
            title: '调整数量',
            key: 'adjustStock',
            type: FormTypes.slot,
            width: '100px',
            placeholder: '请输入${title}',
            defaultValue: '',
            slotName: 'adjustStockSlot',
          },
          {
            title: 'goods_id',
            key: 'goods_id',
            type: 'hidden',
          },

          {
            title: 'goods_spec',
            key: 'goods_spec',
            type: 'hidden',
          },
          {
            title: '调整前数量',
            key: 'beforeStock',
            type: 'hidden',
            width: '100px',
            defaultValue: '',
          },
          {
            title: '调整后数量',
            key: 'afterStock',
            type: 'hidden',
            width: '100px',
            defaultValue: '',
          },
        ],
      },
      url: {
        add: '/storage/stockAdjustApproval/add',
        edit: '/storage/stockAdjustApproval/edit',
        stockAdjustApprovalDetail: {
          list: '/storage/stockAdjustApproval/queryStockAdjustApprovalDetailByMainId',
        },
      },
    }
  },
  created() {},
  methods: {
    /** 调用完edit()方法之后会自动调用此方法 */
    editAfter() {
      const self = this
      // 初始化 fromSpaceData
      self.tableRows = {}
      // 新增时 调整类型默认值为 0：调整库存
      self.model.adjustType = self.model.adjustType ? 1 : 0
      // 根据调整类型调整表单与表格的渲染
      self.adjustTypeChange(self.model.adjustType)
      // 设置表单仓库项默认值
      if (self.storeList) {
        self.setStoreDefault(self.storeList[0].value)
      }

      self.$nextTick(() => {
        self.form.setFieldsValue(
          pick(self.model, 'adjustName', 'fromStoreId', 'toStoreId', 'adjustType', 'adjustReason', 'remark')
        )
      })

      // 加载子表数据
      if (self.model.id) {
        let params = { id: self.model.id }
        self.requestSubTableData(
          self.url.stockAdjustApprovalDetail.list,
          params,
          self.stockAdjustApprovalDetailTable,
          self.tableRowsInit
        )
      }
    },

    /** 调整类型变化 */
    adjustTypeValdator(r, v, c) {
      const self = this
      if (+v !== self.model.adjustType) {
        self.model.adjustType = +v
        /** 改变页面结构 */
        self.adjustTypeChange(+v)
        /** 清理table相关数据 */
        self.tableDataInit()
      }
      c()
    },

    /** 根据调整类型变化改变页面结构 */
    adjustTypeChange(adjustType) {
      const self = this
      // 表单-调整后仓库-显隐
      self.isShowToStoreId = +adjustType

      const columns = self.stockAdjustApprovalDetailTable.columns

      // 根据调整类型对table前两列做出的改变
      columns[0].title = adjustType ? '调整前仓位' : '调整仓位'
      columns[1].type = adjustType ? FormTypes.sel_search : FormTypes.hidden

      // 表格-库存类型且信息状态为待审核-添加调整前数量，调整后数量两列
      let len = columns.length
      adjustType === 0 && self.model.status === 1
        ? (columns[len - 2].type = columns[len - 1].type = FormTypes.input)
        : (columns[len - 2].type = columns[len - 1].type = FormTypes.hidden)
    },

    /** table数据初始化 */
    tableRowsInit({ success: s, result: { records: r } }) {
      const self = this
      if (!s) return false
      for (let i = 0; i < r.length; i++) {
        let { id: rowId, fromSpaceId, goodsId, ...res } = r[i]
        self.$set(self.tableRows, rowId, {
          ...res,
          goodsId,
          fromSpaceId,
          goodsList: [],
          specsList: [],
        })
        self.setGoodsList2specsList(rowId, fromSpaceId, goodsId)
      }
    },
    /** 设置tableRows的对应rowId下的goodsList和specsList */
    async setGoodsList2specsList(i, f, g) {
      const self = this
      /** api 获取仓位下商品列表 */
      let { result: gr } = await self.apiGetGoodsList({ spaceId: f })
      /** api 获取商品下规格列表 */
      let { result: sr } = await self.apiGetSpecsList({ spaceId: f, goodsId: g })

      self.$set(self.tableRows[i], 'goodsList', gr || [])
      self.$set(self.tableRows[i], 'specsList', sr || [])
    },
    /** 设置表单中仓库默认值 */
    setStoreDefault(storeId) {
      const self = this
      if (!self.model.fromStoreId) {
        self.model.fromStoreId = self.model.toStoreId = storeId
        self.$nextTick(() => {
          self.form.setFieldsValue(pick({ fromStoreId: storeId, toStoreId: storeId }, 'fromStoreId', 'toStoreId'))
        })
      }
      // 获取调整前及调整后仓库ID加载仓位列表
      self.tableStoreList({ f: self.model.fromStoreId, t: self.model.toStoreId })
    },

    /**
     *  table 区域 ===================================================================
     */

    /** 行添加删除 */
    rowAdd({ row: { id: rowId } }) {
      const self = this
      const obj = {
        fromSpaceId: '',
        toSpaceId: '',
        goodsId: '',
        goodsSpec: '',
        adjustStock: 0,
        goodsList: [],
        specsList: [],
      }
      self.$set(self.tableRows, rowId, obj)
    },
    rowDel(props) {
      const self = this
      for (let i = 0; i < props.length; i++) {
        const key = props[i]
        self.$delete(self.tableRows, key)
      }
    },

    /** 调整前仓位or调整仓位变化 */
    fromSpaceIdChange(type, value, row, column, callback, target) {
      const self = this
      if (type === 'change') {
        Object.assign(self.tableRows[row.id], {
          fromSpaceId: value,
          goodsId: '',
          goodsSpec: '',
          adjustStock: 0,
          goodsList: [],
          specsList: [],
        })
      }
      callback()
    },
    /** 调整后仓位变化 */
    toSpaceIdChange(type, value, row, column, callback, target) {
      const self = this
      if (type === 'change') {
        self.tableRows[row.id].toSpaceId = value
      }
      callback()
    },

    /** 点击商品获取商品列表 */
    async goodsIdFocus(props) {
      const self = this
      const { rowId } = props
      // 获取仓位下商品
      const { fromSpaceId: spaceId, goodsList = [] } = self.tableRows[rowId]
      if (goodsList.length > 0) return false
      let { result } = await self.apiGetGoodsList({ spaceId })
      self.$set(self.tableRows[rowId], 'goodsList', result)
    },
    /** 商品值发生变化 */
    goodsIdChange(props, value) {
      const self = this
      const { rowId } = props
      Object.assign(self.tableRows[rowId], {
        goodsId: value,
        goodsSpec: '',
        specsList: [],
        adjustStock: 0,
      })
    },

    /** 点击规格获取规格列表 */
    async specsFocus(props) {
      const self = this
      const { rowId } = props
      const { fromSpaceId: spaceId, goodsId, specsList = [] } = self.tableRows[rowId]
      if (specsList.length > 0) return false
      let { result } = await self.apiGetSpecsList({ spaceId, goodsId })
      self.$set(self.tableRows[rowId], 'specsList', result)
    },
    /** 规格值发生变化 */
    specsChange(props, value) {
      const self = this
      const { rowId } = props
      const len = Object.keys(self.tableRows).length
      const rows = Object.values(self.tableRows)
      const adjustType = self.model.adjustType

      if (len > 0 && adjustType === 0) {
        let items = rows.filter(
          (item) => item.fromSpaceId === self.tableRows[rowId].fromSpaceId && item.goodsSpec === value
        )
        if (items.length > 1) {
          this.$message.warning('不可选择同一仓位下同一商品')
          self.tableRows[rowId].goodsSpec = ''
        } else {
          self.tableRows[rowId].goodsSpec = value
        }
      }
    },

    /** 数量值发生变化 */
    adjustStockChange(props, value) {
      this.tableRows[props.rowId].adjustStock = value
    },

    /** 表单-判断表单中那个仓库发生改变 */
    async stockIdValdator(rule, value, callback) {
      const self = this
      let index,
        my_c = []
      if (value !== self.model[rule.field]) {
        self.model[rule.field] = value
        index = rule.field === 'fromStoreId' ? 0 : 1
        let {
          result: { records },
        } = await self.apiGetPlaceList({ id: value })
        records.forEach((item) => {
          my_c.push({
            title: item.spaceCode,
            text: item.spaceCode,
            value: item.id,
          })
        })
        self.$refs[self.refKeys[0]].initialize()
        self.tableRows = {}
        self.$set(self.stockAdjustApprovalDetailTable.columns[index], 'options', my_c)
      }
      callback()
    },

    /** 表格数据重置 */
    tableDataInit() {
      const self = this
      self.tableRows = {}
      self.$refs[this.refKeys[0]].initialize()
    },

    /**
     *  api 区域
     */
    /** 获取商品列表 */
    apiGetGoodsList({ spaceId }) {
      const self = this
      const adjustType = self.model.adjustType
      return getQueryBySpaceId({ spaceId, adjustType })
    },
    /** 获取规格列表 */
    apiGetSpecsList({ spaceId, goodsId }) {
      const self = this
      const adjustType = self.model.adjustType
      return getQueryByGoodsId({ spaceId, goodsId, adjustType })
    },
    /** 获取仓位列表 */
    apiGetPlaceList({ id }) {
      const self = this
      const adjustType = self.model.adjustType
      return getStockPosition({ id, adjustType })
    },

    /** 弹窗-操作-审批 */
    handleApproval(type) {
      const self = this
      self.confirmLoading = true
      postStockApproval({ status: type, id: self.model.id, remark: self.form.getFieldValue('remark') })
        .then((res) => {
          if (res.success) {
            self.$message.success(res.message)
            self.$emit('ok')
            self.close()
          } else {
            self.$message.warning(res.message)
          }
        })
        .finally(() => {
          self.confirmLoading = false
        })
    },

    getAllTable() {
      const self = this
      let values = self.tableKeys.map((key) => getRefPromise(self, key))
      return Promise.all(values)
    },
    /** 整理成formData */
    classifyIntoFormData(allValues) {
      const self = this
      Object.assign(self.model, allValues.formValue)

      let rowIds = Object.keys(self.tableRows),
        arr = []
      for (let i = 0; i < rowIds.length; i++) {
        const rowId = rowIds[i]
        let { goodsList, specsList, ...res } = self.tableRows[rowId]
        arr.push({
          id: rowId,
          ...res,
        })
      }
      return {
        ...self.model, // 展开
        stockAdjustApprovalDetailList: arr,
      }
    },
    /** 仓位列表 */
    async tableStoreList({ f = null, t = null }) {
      const self = this
      if (f || t) {
        let storeIds = [f, t]
        for (let i = 0; i < storeIds.length; i++) {
          if (storeIds[i]) {
            let storeType = i ? 'toStoreId' : 'fromStoreId'
            let {
              result: { records },
              my_c = [],
            } = await self.apiGetPlaceList({ id: self.model[storeType] })
            records.forEach((item) => {
              my_c.push({
                title: item.spaceCode,
                text: item.spaceCode,
                value: item.id,
              })
            })
            self.$set(self.stockAdjustApprovalDetailTable.columns[i], 'options', my_c)
          }
        }
      }
    },
    // 商品搜索过滤
    filterOption(input, option) {
      return option.componentOptions.children[0].text.toLowerCase().indexOf(input.toLowerCase()) >= 0
    },
  },
}
</script>
